//-----------------------------------------------------------------------
// <copyright file="CreateSequenceMetadata.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Steve Short</author>
// <email>v-stshor</email>
// <date>2008-02-06</date>
// <summary>
// Adds a metadata item containing a sequence number to each item in an 
// itemlist.
// </summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks
{
    #region Using directives
    using System;
    using System.Text;
    using Microsoft.Build.BuildEngine;
    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities;
    using Microsoft.Build.Shared;
    #endregion

    /// <summary>
    /// Adds a metadata item containing a sequence number to each item in the itemlist passed.
    /// </summary>
    /// <remarks>
    /// <code>
    /// <![CDATA[<CreateSequenceMetadata
    ///     ItemList="itemList"
    ///     MetadataName="metadataName"
    ///     FormatString="formatString"
    ///     [Start="startNumber"]
    ///     [Increment="incrementNumber"]
    ///     >
    ///     <Output TaskParameter="ItemList" ItemName="outputList" />
    /// </CreateSequenceMetadata>]]>
    /// </code>
    /// <para>where:</para>
    /// <para><i>ItemList (Required)</i></para>
    /// <para>The itemlist that the metadata is to be added to. This is also the output itemlist.</para>
    /// <para><i>MetadataName (Required)</i></para>
    /// <para>The name of the metadata to be created for each item.</para>
    /// <para><i>FormatString (Required)</i></para>
    /// <para>A format string for the sequence number. This is a String.Format() type format string and should include the {0} placeholder for the sequence number.</para>
    /// <para><i>Start (optional)</i></para>
    /// <para>An optional numeric value to start the sequence number at. This defaults to 1 if not specified.</para>
    /// <para><i>Increment (Optional)</i></para>
    /// <para>An optional numeric value used to increment the sequence number by. This defaults to 1 if not specified.</para>
    /// </remarks>
    /// <example>
    /// This example will output an itemlist called IndexedNames based on the Names itemlist with
    /// an additional metadata item called Index. Each value in Index will be a unique sequential
    /// number of three digits with leading zeroes.
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <CreateSequenceMetadata
    ///             MetadataItem="Index"
    ///             FormatString="{0:000}"
    ///             ItemList="@(Names)">
    ///                 <Output TaskParameter="ItemList" ItemName="IndexedNames" />
    ///         </CreateSequenceMetadata>
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    ///     /// <example>
    /// The second example is similar to the previous one but demonstrates how the FormatString parameter
    /// may be used to create string values that are more than just a sequence number. Also, Start 
    /// and Increment values are used to set values other than 1 for these parameters. The metadata
    /// values created will be NAME1000, NAME1010, etc. 
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <CreateSequenceMetadata
    ///             MetadataItem="Index"
    ///             FormatString="NAME{0:0000}"
    ///             ItemList="@(Names)"
    ///             Start="1000"
    ///             Increment="10">
    ///                 <Output TaskParameter="ItemList" ItemName="IndexedNames" />
    ///         </CreateSequenceMetadata>
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public class CreateSequenceMetadata : TaskBase
    {
        private ITaskItem[] itemList;
        private string formatString;
        private string metadataName;
        
        private int start = 1;
        private int increment = 1;        

        /// <summary>
        /// A format string for the sequence number. This is a String.Format() type format string and should include the {0} placeholder for the sequence number.
        /// </summary>
        [Required]
        public string FormatString
        {
            get { return this.formatString; }
            set { this.formatString = value; }
        }

        /// <summary>
        /// The name of the metadata to be created for each item.
        /// </summary>
        [Required]
        public string MetadataName
        {
            get { return this.metadataName; }
            set { this.metadataName = value; }
        }

        /// <summary>
        /// An optional numeric value to start the sequence number at. This defaults to 1 if not specified.
        /// </summary>
        public int Start
        {
            get {return this.start; }
            set { this.start = value; }
        }

        /// <summary>
        /// An optional numeric value used to increment the sequence number by. This defaults to 1 if not specified.
        /// </summary>
        public int Increment
        {
            get {return this.increment; }
            set { this.increment = value; }
        }

        /// <summary>
        /// The itemlist that the metadata is to be added to. This is also the output itemlist.
        /// </summary>
        [Required]
        [Output]
        public ITaskItem[] ItemList 
        { 
            get { return this.itemList; }
            set { this.itemList = value; }
        }

        protected override void InternalExecute()
        {
            // Initialise counter to start value:
            int counter = this.start;

            foreach (ITaskItem item in this.itemList)
            {
                // Format the counter as specified by our caller:
                string metadataValue = string.Format(this.formatString, counter);

                // Set the value as a metadata item:
                item.SetMetadata(this.metadataName, metadataValue);
                
                // Increase counter by increment value:
                counter += this.increment;
            }

            return;
        }
    }
}
